﻿using System;
using System.Collections.Generic;
using CRC.GestionSalones.Dominio.Clases;
using NHibernate;
using CRC.Inspecciones.Dominio.Clases;
using System.Collections;
using CRC.GestionSalones.Presentacion;

namespace CRC.GestionSalones.Controladores
{
    public class ControladorAltaSalon : ControladorBaseSalon, IControladorCongregacion
    {
        private static String strQryExisteProyecto = "from Salon s where s.Proyecto='{0}'";
        private static String strQryExisteCongregacion = "from Congregacion c where c.NombreCRC=:NombreCRC";
        
        private Salon salon = null;
        private Congregacion cong = null;
        private Persona supPresidente = null;
        private Persona secretario = null;
        private Persona supCircuito = null;

        public void nuevoSalon(
            String pStrNumProyecto, 
            String pStrNombreSalon, 
            int? pIntProvincia, 
            int? pIntMunicipio, 
            int pIntZona,
            String pStrDireccion,
            String pStrCPostal,
            String pStrAltitud,
            String pStrLatitud,
            int? pIntTelefono,
            String pStrObservaciones,
            String pStrTipoPropiedad
        ) 
        {
            ISession session = null;
            ITransaction tx = null;
            try 
            {
                session = NHibernate.NHibernateHelper.GetCurrentSession();
                tx = session.BeginTransaction();

                IList res = session.CreateQuery(String.Format(strQryExisteProyecto, pStrNumProyecto)).List();
                if (res.Count > 0) {
                    throw new ApplicationException("El número de proyecto ya está asignado");
                }

                Municipio munic = null;
                if (pIntMunicipio !=null) 
                    munic = (Municipio)session.Get(typeof(Municipio), pIntMunicipio);
                TipoPropiedad tipoPropiedad = (TipoPropiedad)session.Get(typeof(TipoPropiedad), pStrTipoPropiedad);

                Zona zona = (Zona)session.Get(typeof(Zona), pIntZona);
                Salon nuevoSalon = new Salon(pStrNumProyecto, pStrNombreSalon, null, 
                    munic, zona, pStrDireccion, pStrCPostal, pStrAltitud,
                    pStrLatitud, pIntTelefono, pStrObservaciones, tipoPropiedad
                );

                this.salon = nuevoSalon;

                tx.Commit();
            }
            catch (HibernateException he) {

                if (tx != null) tx.Rollback();
                session.Close();
                throw he;
            }

        }

        #region " Congregaciones "

            public void añadirCongregacion(
                int pIntNum, 
                String pStrNombreCRC, 
                String pStrNombreSucursal, 
                Boolean pbEsAnfitriona,
                String pStrObservaciones)
            {
                ISession session = null;
                ITransaction tx = null;

                try
                {
                    session = NHibernate.NHibernateHelper.GetCurrentSession();
                    tx = session.BeginTransaction();

                    //post: Si hemos añadido congregacion con nombre pStrNombreCRC -> excepcion
                    foreach (Congregacion ass in this.salon.Asistentes)
                    {
                        if (ass.NombreCRC.CompareTo(pStrNombreCRC) == 0) 
                            throw new ApplicationException("¡Ya existe una congregación con este nombre!");
                    }

                    IQuery qry = session.CreateQuery(strQryExisteCongregacion).SetParameter("NombreCRC", pStrNombreCRC);
                    int nCongAux = qry.List().Count;

                    if (nCongAux > 0)
                        throw new ApplicationException("¡Ya existe una congregación con este nombre!");

                    this.cong = this.salon.nuevaCongregacion(
                        pIntNum,
                        pStrNombreCRC,
                        pStrNombreSucursal,
                        pbEsAnfitriona,
                        pStrObservaciones,
                        this.supPresidente,
                        this.secretario,
                        this.supCircuito
                    );
                   
                    tx.Commit();

                    this.supPresidente = null;
                    this.secretario = null;
                    this.supCircuito = null;
                }
                catch (HibernateException he) {

                    if (tx != null) tx.Rollback();
                    session.Close();
                    throw he;
                }
            }

            public Object[] obtenerDatosCongregacion(String pStrNombreCRC) 
            {
                String strNombPresid = String.Empty, strNombSecre = String.Empty, strNombSupCircuito = String.Empty;

                foreach (Congregacion c in this.salon.Asistentes) 
                {
                    if (c.NombreCRC.CompareTo(pStrNombreCRC) == 0) {
                        
                        this.cong = c;
                        this.supPresidente = c.Presidente;
                        this.secretario = c.Secretario;
                        this.supCircuito = c.SuperintendenteCircuito;
                        
                        if (this.cong.Presidente != null) strNombPresid = this.cong.Presidente.NombreCompleto;
                        if (this.cong.Secretario != null) strNombSecre = this.cong.Secretario.NombreCompleto;
                        if (this.cong.SuperintendenteCircuito != null) strNombSupCircuito = this.cong.SuperintendenteCircuito.NombreCompleto;

                        return new Object[] { 
                            this.cong.Numero, 
                            this.cong.NombreCRC, 
                            this.cong.NombreSucursal,
                            this.cong.EsAnfitriona,
                            strNombPresid , 
                            strNombSecre, 
                            strNombSupCircuito, 
                            this.cong.Observaciones
                        };
                    }
                }
                return null;
            }

            public void modificarCongregacion(
                    int pIntNum,
                    String pStrNombreCRC,
                    String pStrNombreSucursal,
                    Boolean pbEsAnfitriona,
                    String pStrObservaciones)
            {
                ISession session = null;
                ITransaction tx = null;

                try
                {
                    session = NHibernate.NHibernateHelper.GetCurrentSession();
                    tx = session.BeginTransaction();

                    //post: Si hemos añadido congregacion con numero pIntNum -> excepcion
                    foreach (Congregacion ass in this.salon.Asistentes)
                    {
                        if ((ass != this.cong) && (ass.NombreCRC.CompareTo(pStrNombreCRC) == 0))
                            throw new ApplicationException("¡Ya existe una congregación con este nombre!");
                    }

                    if (this.cong.Numero != pIntNum) 
                    { 
                        IList<Congregacion> congAux = session.CreateQuery(String.Format(strQryExisteCongregacion, pStrNombreCRC)).List<Congregacion>();
                        if (congAux.Count > 0)
                            throw new ApplicationException("¡Ya existe una congregación con este nombre!");
                    }

                    this.cong.Numero = pIntNum;
                    this.cong.NombreCRC = pStrNombreCRC;
                    this.cong.NombreSucursal = pStrNombreSucursal;
                    this.cong.EsAnfitriona = pbEsAnfitriona;
                    this.cong.Presidente = this.supPresidente;
                    this.cong.Secretario = this.secretario;
                    this.cong.SuperintendenteCircuito = this.supCircuito;
                    this.cong.Observaciones = pStrObservaciones;

                    tx.Commit();

                    this.supPresidente = null;
                    this.secretario = null;
                }
                catch (HibernateException he)
                {

                    if (tx != null) tx.Rollback();
                    session.Close();
                    throw he;
                }
            }


            public void eliminarCongregacion(String pStrNombreCRC) 
            {
                ISession session = NHibernate.NHibernateHelper.GetCurrentSession();
                foreach (Congregacion c in this.salon.Asistentes)
                {
                    if (c.NombreCRC.CompareTo(pStrNombreCRC) == 0)
                    {
                        this.salon.Asistentes.Remove(c);
                        c.Salon = null;
                        session.Delete(c);
                        session.Flush();
                    }
                    return;
                }
            }

            #region " Presidente "

                public void nuevoPresidente(
                    String pStrNombre, 
                    String pStrApellido1, 
                    String pStrApellido2, 
                    String pStrMovil, 
                    String pStrFijo, 
                    String pStrEmail) { 

                    ISession session = null;
                    ITransaction tx = null;

                    try {

                        session = NHibernate.NHibernateHelper.GetCurrentSession();
                        tx = session.BeginTransaction();

                        TipoPersona tipoPresidente = (TipoPersona)session.Get(typeof(TipoPersona), 1);
                        this.supPresidente = new Persona(pStrNombre, pStrApellido1, pStrApellido2,
                        pStrFijo, pStrMovil, null, pStrEmail, tipoPresidente);

                        tx.Commit();

                    }
                    catch(HibernateException he){
                        if (tx != null) {
                            tx.Rollback();
                            session.Close();
                        }
                        throw he;
                    }
                }

                public Object[] obtenerDatosPresidente()
                {
                    if (this.supPresidente != null) 
                    {
                        return new Object[] { 
                            this.supPresidente.Nombre, 
                            this.supPresidente.Apellido1, 
                            this.supPresidente.Apellido2, 
                            this.supPresidente.TelefonoFijo, 
                            this.supPresidente.TelefonoMovil1, 
                            this.supPresidente.Email 
                        };
                    }
                    return null;
                }

                public void modificarDatosPresidente(
                    String pStrNombre,
                    String pStrApellido1,
                    String pStrApellido2,
                    String pStrMovil,
                    String pStrFijo,
                    String pStrEmail) 
                {
                    this.supPresidente.Nombre = pStrNombre;
                    this.supPresidente.Apellido1 = pStrApellido1;
                    this.supPresidente.Apellido2 = pStrApellido2;
                    this.supPresidente.TelefonoMovil1 = pStrMovil;
                    this.supPresidente.TelefonoFijo = pStrFijo;
                }

                public void asignarPresidente(int pIntPresidente)
                {
                    ISession session = null;

                    try
                    {
                        session = NHibernate.NHibernateHelper.GetCurrentSession();
                        this.supPresidente = (Persona)session.Get(typeof(Persona), pIntPresidente);
                    }
                    catch (HibernateException he) 
                    {
                        session.Close();
                        throw he;
                    }
                }

            #endregion

            #region " Secretario "

                    public void nuevoSecretario(
                        String pStrNombre,
                        String pStrApellido1,
                        String pStrApellido2,
                        String pStrMovil,
                        String pStrFijo,
                        String pStrEmail)
                    {
                        ISession session = null;
                        ITransaction tx = null;

                        try
                        {
                            session = NHibernate.NHibernateHelper.GetCurrentSession();
                            tx = session.BeginTransaction();

                            TipoPersona tipoSecretario = (TipoPersona)session.Get(typeof(TipoPersona), 2);
                            this.secretario = new Persona(pStrNombre, pStrApellido1, pStrApellido2,
                                pStrFijo, pStrMovil, null, pStrEmail, tipoSecretario);

                            tx.Commit();
                        }
                        catch (HibernateException he)
                        {
                            if (tx != null) tx.Rollback();
                            session.Close();
                            throw he;
                        }
                    }

                    public Object[] obtenerDatosSecretario()
                    {
                        if (this.secretario != null)
                        {
                            return new Object[] { 
                                this.secretario.Nombre, 
                                this.secretario.Apellido1, 
                                this.secretario.Apellido2, 
                                this.secretario.TelefonoFijo, 
                                this.secretario.TelefonoMovil1, 
                                this.secretario.Email 
                            };
                        }
                        return null;
                    }

                    public void modificarDatosSecretario(
                        String pStrNombre,
                        String pStrApellido1,
                        String pStrApellido2,
                        String pStrMovil,
                        String pStrFijo,
                        String pStrEmail)
                    {
                        this.secretario.Nombre = pStrNombre;
                        this.secretario.Apellido1 = pStrApellido1;
                        this.secretario.Apellido2 = pStrApellido2;
                        this.secretario.TelefonoMovil1 = pStrMovil;
                        this.secretario.TelefonoFijo = pStrFijo;
                        this.secretario.Email = pStrEmail;
                    }

                    
                    public void asignarSecretario(int pIntSecretario)
                    {
                        ISession session = null;

                        try
                        {
                            session = NHibernate.NHibernateHelper.GetCurrentSession();
                            this.secretario = (Persona)session.Get(typeof(Persona), pIntSecretario);
                        }
                        catch (HibernateException he)
                        {
                            session.Close();
                            throw he;
                        }
                    }

                #endregion

            #region " Superintendente circuito "

                    public void asignarSuperintendenteCircuito(int pInSupCircuito)
                    {
                        ISession session = null;

                        try
                        {
                            session = NHibernate.NHibernateHelper.GetCurrentSession();
                            this.supCircuito = (Persona)session.Get(typeof(Persona), pInSupCircuito);
                        }
                        catch (HibernateException he)
                        {
                            session.Close();
                            throw he;
                        }
                    }

                    public Object[] obtenerDatosSuperintendenteCircuito() 
                    {
                        if (this.supCircuito != null)
                        {
                            return new Object[] { 
                                this.supCircuito.Nombre, 
                                this.supCircuito.Apellido1, 
                                this.supCircuito.Apellido2, 
                                this.supCircuito.TelefonoFijo, 
                                this.supCircuito.TelefonoMovil1, 
                                this.supCircuito.Email 
                            };
                        }
                        return null;
                    }

                    public void modificarDatosSupCircuito(
                                    String pStrNombre,
                                    String pStrApellido1,
                                    String pStrApellido2,
                                    String pStrMovil,
                                    String pStrFijo,
                                    String pStrEmail)
                    {
                        this.supCircuito.Nombre = pStrNombre;
                        this.supCircuito.Apellido1 = pStrApellido1;
                        this.supCircuito.Apellido2 = pStrApellido2;
                        this.supCircuito.TelefonoMovil1 = pStrMovil;
                        this.supCircuito.TelefonoFijo = pStrFijo;
                        this.supCircuito.Email = pStrEmail;
                    }

            #endregion

        #endregion

        public int FinAltaSalon() { 
            ISession session = null;
            ITransaction tx = null;

            try
            {
                session = NHibernate.NHibernateHelper.GetCurrentSession();
                tx = session.BeginTransaction();

                session.Save(this.salon);
                tx.Commit();

                return this.salon.Id;
            }
            catch (HibernateException he) {
                if (tx != null) tx.Rollback();
                session.Close();
                throw he;
            }
        }

        public void limpiarEstado()
        {
            this.supCircuito = null;
            this.supPresidente = null;
            this.secretario = null;
        }
    }
}
